package com.p2l.letterblocks;

import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.WindowManager;

public class GamePersistor extends Activity {
	public static float SCALE = 0;
	public static int DEFAULT_ORIENTATION = 0;
	public static int SCREEN_HEIGHT = 0;
	public static int SCREEN_WIDTH = 0;
	
	private GameController controller;
	private GamePersistor persistor;
	private GameModel model;
	private GameView view;

	private SharedPreferences preferences;
	private SQLiteDatabase sqlite;
	private Database db;
	
	public boolean loading;
	public float music, effects, voice;
	public int userId, levelId, difficulty, hand;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().setFormat(PixelFormat.RGBA_8888);
		
		System.gc();
		
		persistor = this;
		loading = true;
		
		preferences = getSharedPreferences("LetterBlocks", MODE_PRIVATE);
		music = preferences.getFloat("music", 1.0f);
		effects = preferences.getFloat("effects", 1.0f);
		voice = preferences.getFloat("voice", 1.0f);
		hand = preferences.getInt("hand", 1);
		
		final WindowManager.LayoutParams brightness = getWindow().getAttributes();
		brightness.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
        getWindow().setAttributes(brightness);
		
		DisplayMetrics metrics = getResources().getDisplayMetrics();
		SCREEN_WIDTH = metrics.widthPixels;
		SCREEN_HEIGHT = metrics.heightPixels;
		SCALE = metrics.density;
		
		Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
		DEFAULT_ORIENTATION = display.getOrientation();
		
		setContentView(R.layout.game);
		
		controller = new GameController(this);
		
		view = (GameView) findViewById(R.id.view);
		view.setOnTouchListener(controller);
		model = new GameModel(this);

		userId = getIntent().getIntExtra("userId", -1);
		levelId = getIntent().getIntExtra("levelId", -1);
		difficulty = getIntent().getIntExtra("difficulty", LevelLoader.EASY);
		if (levelId != -1) {
			boolean loaded = LevelLoader.loadLevel(persistor, levelId, userId, difficulty);
			if (!loaded) {
				Log.e("LetterBlocks", "could not load level");
				finish();
			} else {
				loading = false;
			}
		} else {
			Log.e("LetterBlocks", "levelId = -1");
			finish();
		}
	}
    
    @Override
    public void onPause() {
    	super.onPause();
    	controller.onPause();
    	model.onPause();
    	view.onPause();

		db.close();
    }
    
    @Override
    public void onResume() {
    	super.onResume();
    	controller.onResume();
    	model.onResume();
    	view.onResume();
    	
    	db = new Database(persistor);
    	sqlite = db.getWritableDatabase();
    }
    
    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	controller.onDestroy();
    	model.onDestroy();
    	view.onDestroy();
    	
    	controller = null;
    	model = null;
    	view = null;
    	
		System.gc();
    }
    
    public GameModel getModel() {
    	return model;
    }
    
    public GameView getView() {
    	return view;
    }
    
    public int delta() {
    	return (int)(Calendar.getInstance().getTimeInMillis() - model.getLastUpdate());
    }
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    	return controller.onKeyDown(keyCode, event);
    }
    
    public void runLevelCompletedTask(String sql, long column) {
    	new LevelCompletedTask().execute(sql, "" + column);
    }
	
	public class LevelCompletedTask extends AsyncTask<String, Void, Boolean> {
		private SQLiteDatabase sqlite;
		private Database db;
		
    	@Override
		protected Boolean doInBackground(String... params) {
        	db = new Database(persistor);
        	sqlite = db.getWritableDatabase();
        	
			try {
				InputStream in = Server.open(params[0]);
				XmlPullParser parser = Server.toXmlParser(in);
				parser.nextTag();
				int id = XmlParser.getInt(parser, "Id");
				in.close();
				
				String where = "id='" + params[1] + "'";
				String[] columns = { Database.COLUMS_LEVELS_COMPLETED[0] };
				String[] values = { "" + id }; 
				long result = db.update(sqlite, Database.TABLE_NAME_LEVELS_COMPLETED, columns, values, where);

				in = Server.open(Server.URL_DAILY_COIN + "?userId=" + persistor.userId);
				parser = Server.toXmlParser(in);
				parser.next();
				boolean daily = XmlParser.getBoolean(parser, "Result");
				in.close();
				if (daily) {
					in = Server.open(Server.URL_INSERT_DAILY_COIN + "?userId=" + persistor.userId);
					in.close();
				}
				
				Intent intent = getIntent();
				intent.putExtra("daily", daily);
				persistor.setResult(Activity.RESULT_OK, intent);
				
				if (result != -1)
					return true;
				else
					return false;
			} catch (IOException e) {
				Log.e("LetterBlocks", e.toString());
				return false;
			} catch (XmlPullParserException e) {
				Log.e("LetterBlocks", e.toString());
				return false;
			}
		}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
			db.close();
	    	this.cancel(true);
	    }
	}
	
	public void runSoundTask(String url, String name, String word) {
		new SoundTask().execute(url, name, word);
	}
	
	public class SoundTask extends AsyncTask<String, Void, Boolean> {
		String url, name, word;
		
    	@Override
		protected Boolean doInBackground(String... params) {
			try {
	    		url = params[0];
	    		name = params[1];
	    		word = params[2];
	    		
				InputStream in = Server.open(url);
				Server.saveSoundFile(persistor, in, "sound/", name);
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}
    		return true;
    	}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
	    	this.cancel(true);
	    	if (success) {
	    		//TODO null pointer hvis man leaver inden lydfilen er hentet
	    		//TODO skal ikke afspille lydende hvis den er i gang med at hente lydfilen
	    		getModel().getEndLevel().setWord(word);
	    		loading = false;
	    	} else {
				Intent intent = getIntent();
				intent.putExtra("sound", true);
				persistor.setResult(Activity.RESULT_OK, intent);
				finish();
	    	}
	    }
	}
	
	public void runBitmapTask(String url, String name, int index) {
		new BitmapTask().execute(url, name, "" + index);
	}
	
	public class BitmapTask extends AsyncTask<String, Void, Boolean> {
    	@Override
		protected Boolean doInBackground(String... params) {
			try {
	    		String url = params[0];
	    		String name = params[1];
	    		int index = Integer.parseInt(params[2]);
	    		
				InputStream in = Server.open(url);
				Bitmap b = BitmapFactory.decodeStream(in);
				Server.saveBitmap(persistor, Server.FOLDERS[index], name + "_game.png", b);
				in.close();
				
				switch (index) {
				case 0:
					getModel().getBear().setHead(b);
					break;
				case 1:
					getModel().getBear().setBody(b);
					break;
				case 2:
					getModel().getBear().setLegs(b);
					break;
				case 3:
					getModel().getBear().setBelt(b);
					break;
				case 4:
					getModel().getBear().setAccessories(b);
					break;
				}
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			} catch (OutOfMemoryError e) {
				e.printStackTrace();
				return false;
			} catch (NullPointerException e) {
				e.printStackTrace();
				return false;
			}
    		return true;
    	}
    
	    @Override
	    protected void onPostExecute(Boolean success) {
	    	this.cancel(true);
	    }
	}
}